welcome everyone I hope you're enjoying
you night so far it's a I must say if
anyone who came to Berlin last year the
food is much better this year so I'm
here to talk to you guys about a
universal render pipeline but more
specifically how it was used in the boat
attack demo that you might have seen at
the keynote and there has been in
development alongside what was
lightweight were in the pipeline but now
called Universal render pipeline my name
is Andre McGrail and I am a technical
artist at unity so here's a short
overview of what I'll be talking about
today I have a short intro just show
some like some awesome old kind of
footage from boat demo and where it's
come from I'll briefly go over some of
the features that I've used just in
universe huapi in general like very
basic kind of the quality settings the
render pipeline asset that kind of stuff
just briefly go over there then we'll
dive into shader graph I'll show you
some of the shaders that were set up
from a basic one to a more complex one
with a custom function nodes etc jump
onto chemical Mex these replaced kind of
the old callbacks in unity so they're
good to know and understand and then
move on to render pass features which is
kind of our a nice easy wrapper for
creating extra passes or customizing the
render and Universal render pipeline so
at the very early version of the bodemer
looked quite a bit different this wasn't
any kind of like show on the actual like
where you're in the pipeline at the time
obviously it just started out at a very
basic phase already back here we had the
ability to be able to pull off planner
reflections this head obviously changed
quite a bit since it was created then
different callbacks etc and now this is
what it will look like at you know I
bill and which was just over a year ago
I think now again quite you know a lot
more is in there we've got water
we've got you know the planner of
fictions coming in and that kind of
stuff but we didn't have any of the
render pass features and the custom
renderer stuff that wasn't really
integrated into light way we're into
pipeline at the time we had it back
internally as we were using it in the
actual forward renderer but it wasn't
exposed and it wasn't a nice easy kind
of clean API for users to be able to
pick up on and then this is kind of what
it looks like today here you can see we
added the day/night kind of circuit
cycle we've got planner of fiction's
going on stool but now they're using the
new callbacks there's some renderer
features that are adding extra details
into the water which can go on about and
a lot of heavy kind of shader graph
usage because this is kind of very nice
at this point so I'm gonna dive into the
demo now here's the link for the boda
check github repo i've got it in the
actual tree the branch demo work this is
the branch we've been using for unite so
this has a lot of the more recent
updates and it is recommended if you're
gonna load up a 19.3 to use this version
so just dive over into the editor here
and first off let's just have a look at
what it what it please like who was it
an instant crash nice best way to start
a demo look at that yeah that's that one
again so some things I'll show you here
is that we we got up reading on
essentially wide range of devices we had
it running on six devices live on stage
at the keynote which was actually quite
terrifying for me you know never bring
six devices live onstage to demo at once
it was definitely a kind of a heart
palpitating moment so if we have the
demo and see if we can play at this time
we're gonna get in a infinite crash loop
no we're going okay so it's just you'd
make use of cinema sheen here by the way
and I've got this greedy camera taking
all the control so I'll just go back to
the bog so
essentially the idea of this demo was to
create a vertical slice of a boat racing
game you know a big thing we started to
do recently at unity is the production
driven development and this is really
needed now he's crashed I made it this
is like it's super useful like we make
sense to build a use case and then test
those features that we create at the
same time because we could go ahead and
make a feature but without trying it out
and real you know world like scenarios
we're not going to know whether it ticks
all the boxes or I can do all the things
we would like it to do so here I've
managed to make use of quite a lot of
features there in Universal Arena
pipeline we're using a shader graph so
that's used quite heavily you use a
custom renderer features which is also
the custom render pass system this was
used to add caustics in the water it was
also used to add the essentially there's
a water effects pass that creates the
foam and the trails of the boats
it also helps create little foam
splashes around each of the floating
objects it makes use of the burst system
so c-sharp jobs they're used to
calculate height positions in the water
so we can figure out whether you know
certain parts of the boat underneath the
water and apply buoyancy back on it so
it was a good mesh of features and it
has been very useful every time we've
done massive changes to the universe or
in the pipeline to see if we've broken
anything or if something needed some
more work and polishing so to get it
running on all the devices that we
showed off at the keynote it is one
project we can literally go through and
switch between all the build targets
build out and then that's what we have
to do and this was kind of achieved by
now the fact that we've got you know if
you've used lightweight before I've used
script or inner pipe lines you know that
we can add in the script we're in the
pipeline asset and the graphic settings
we've now added this ability to override
this on a per quality level basis and
this is really useful because now you
don't have to try and create a script or
kind of create your own system to switch
out these render pipeline assets
depending on
for more maybe the capability of the
device that you're building to so here
we can see we've got a render pipeline a
set high and if we go down to medium got
a medium one low etc and this is just
where we shaders recompiling this is
where we can like turn off certain
things so for example the low quality
sitting doesn't have shadow cascades
because there's a lot of extra objects
that we're rendering and you know we get
blurry eye shadows but you know it's
fine especially if it's on a mobile
device you've got a small screen you're
not going to notice this difference and
then we can go up cascade so shadow like
resolution up throughout these if these
aren't assigned here then obviously or
just fall back to the one that's it in
the graphic settings but it's a super
nice convenient way to handle quality
levels in scaling across these platforms
as you can see here I don't even allow
like high to be used on mobile devices
if you get stripped out and then things
like WebGL only has low and it's it for
that okay so let's have a look at some
shader graph shaders because I love the
tool I didn't know how to write a shader
before I joined unity which was just
over two years ago I had to learn very
quickly being on the graphics team it
turns out you need to know a lot about
shaders and there's a lot to know about
shaders so I quickly learned but to be
fair when shader graph came in I was
like well it's just it's just easier
especially if you want to do just some
quick experimental stuff you want to try
out some ideas before even committing to
code it's just a nice easy way to get
there and the shader code that shader
graph producers it was actually really
quite nice so for example I'm going to
show you one of the shaders that are
made which is called yeah well a cliff
shader it seems she is used on all the
cliffs in the level the first iteration
of this all the texture maps and etc
were begged down just out of substance
painter so these were using the normal
litter in Universal and you know I
painted grass on top of the cliffs you
know the kind of rocky on the sides and
down where they entered the water I got
you know darker or in a
more like glossy so this was you know it
looked okay but I wanted to reuse rocks
over and over again I don't want to have
you know a ton of unique textures for
each rock depending on where it was so
being able to utilize shader graph
something like this made a lot of sense
so at this point I can take that
information and shader graph I can take
the objects position the hype the
normals etc and build these shaders they
react to the environment around it which
means you kind of get the semi
procedural kind of world building which
is great so for example if we move this
cliff down we can see this kind of a
darkening gradient around the bottom of
it where it is also getting quite glossy
so if we move in here good we can see it
is quite shiny at the base of it and
this is also the same for the grass so
the grass starts happening at a certain
level and it also fades off depending on
the angle so now we can rotate and the
grass will stick on top and on the sides
the rocks will come so no longer did I
have to worry about you know keeping all
my rocks that I had hard-coded painted
down shaders I mean textures sorry at
the positions they were painted for so
now I could if I'd like the top of a
rock and I wanted that just poking out
of the ocean somewhere I could do it and
it would look like it's meant to be
there so we have a look at the shader
and let it compile now it's fairly large
but I have a little bit of a step
through of it so the great thing about
shader graph is now we've got the
ability to group up things and you know
this did not look this neat not long ago
it was a giant mess and I was like well
I gotta show this to a ton of people and
they've got to make sense of it I'm used
to making noodles and yeah big spaghetti
mess but to be able to explain or show
off something you really want to be able
to use groups and also helps in if
you're in a big team being able to share
shaders around and people can you
understand what's actually going on
so it makes use of some normal things
such as you know the grass coming in
grass comes in with Victor's of the
normals and we can blend that in so this
is just grabbing the grass the normal
and tiling it across the object down
here we then have the actual mask
between the rock and the grass we go
back here we can see it's a position of
it so it's using the position here to
essentially get whereabouts it is height
wise and this can give us the mask for
you know a rocks way down close to the
water line it's not going to have a
grass growing on it but if it gets up
high enough in the mountains it'll get
some grass appearing seam here with the
witness it's also using another position
to add that you know higher level of
gloss around the base and then we do
things like actually I create the rock
smoothness there is no smoothness map as
such so the input map is actually if we
head back here for the albedo texture I
get the color for it but I'm also using
the Alpha Channel to store some cavity
maps so they're starting to think about
terms of legs something like substance
designer and/or substance painter we've
got these kind of masks generated kind
of maps so this would just pump straight
out of substance as a cavity map and
then I can bring it into shadow graph
and actually create you know shading
properties based off the sceva D map
using you know meth remapping all that
kind of stuff and it means you can
create this kind of reusable procedural
shader system which is really convenient
and I mean this is the same shader
that's running on the mobile device
there's no difference from the phone
version to the console version it's it's
performed and performant enough that we
can just use it everywhere so if we go
back have a look at another shader which
is a bit more complex and using some
more some more of the kind of key
features of shader graph if we go to the
vegetation so
here we got some palm trees like that
again and you can see we've got kind of
like a subsurface effect now this is an
subsurface shader that's with universal
this is just a shader graph shader and
we can achieve stuff like this now with
things like the custom function node
which it's us to be able to use some
hlsl inside shader graph there's some
other abilities that we can do here
that's going to be hard to see but
essentially there is if we drop down to
low quality sitting we should see the
lords take over nope it's Krang goes way
down okay now we can see my lovely
billboards that I made they're not that
great but essentially we can make use of
the LOD information coming from the Lord
component on the game object and we can
make use of this and switch out between
our high res mesh and our low bail like
low res billboard so it's open up this
so this graph looks a little simpler in
terms of the amount of nodes but that's
because of two things one it's using
custom function node so it's doing some
code calculations within a single node
and the other thing is that makes heavy
use of what we call sub graphs so sub
graphs are seems to be a graph within
the shader graph and these can keep
going deeper and deeper so for starters
the trees themselves have a bit of sway
with the wind they you know the leaves
float around the tree itself bins and
this is all the like entirely
encapsulated in a sub graph the cool
thing about this is that we can reuse it
in another shader graph if we want it if
we wanted to create another variation of
the vegetation shader we can just
straight full drag and drop in this
video
and deformation and if we go into this
will then load up the sub graph there
fullscreen so that's not gonna work and
here we have the essentially the node
network that is deforming these vertex
positions and we've got essentially you
know it's it's similar to a shader graph
shader itself it has properties and
these properties seen as the inputs to
the sub graph node that you get and the
outputs on an output node and here you
can also add as many as you want there
different types name them etc and
they'll appear back up on the sub graph
here we've actually got you know this is
a suti taking vertex positions it's
figuring out the origin it's doing some
sine waves to bend essentially the
vertex positions based off a few vertex
colors so the vertex colors are used as
masks so is simply a copy of the
technique that was used in crisis for
the vegetation there and there's a
really good write-up on GPU gems but we
can see here there's a custom function
and there's also this this is smooth
triangle wave this is a actual another
sub graph so we can open up this and we
go yet another layer deeper into this
graph
and this is a bit more simpler but we've
got some nodes they just come in they're
doing some calculations on the victor
individual victor components of this now
this could all be done probably in a
custom function node the custom function
node could contain the entire HLSL
information for the vegetation
deformation but it is really nice also
being able to do it and a node based
system is very artist friendly you can
look at it and if you know if you used
to know bay stuff it's a very nice way
to work and the code that it generates
is going to be pretty much similar
performance wise to the code that you'd
write anyway and again I won't go into
this but this is another sub graph as
well this moves to curve so now if we go
back up to vegetation
I'm sure but about the custom function
node so here we have a subsurface
scattering kind of group that I've made
and the main reason this uses this the
custom function node is for getting the
light information that's in Universal
render pipeline so here I've just got a
group it's called main light this is
currently the code I've put in only
makes this vegetation shader work with a
one main directional light I haven't put
in the looping code to handle multiple
lights but here we need the world
position of the actual object so we're
getting Medan and in this custom
function node is actually looking at an
external HLSL file called custom
lighting here we also have a name so
this is the name of the function that it
will look for in that custom lighting
function hlsl file so I was looking for
a function and they Accord main light
here are the outputs that that function
has and also the input so the only input
is the world position but then it
outputs the direction the color some of
the attenuation of this light
so I'll just load up and show you what
this custom custom lighting function
though it looks like so we have two
methods in here I've added a second one
this is for used actually in the cloud
shader that I've got and it's just to
get the ambient lighting so this is
quite handy and I'll show you I can
quickly show that later as well but the
one we're talking about now is the main
light so you'll notice that in the name
of the actual custom function note that
I had I only had main light I didn't
have main light underscore half and this
is how shadow graph can do precision
based on the nodes so in jeddah graph
now supports either float position or
half position depending on you know
whether you need the edge information
this is especially important when you're
looking at mobile devices you want to be
doing half wherever you can if you don't
need the extra precision values here is
a little bit of code for the shader
graph preview because the shader graph
preview itself isn't using the render
pipelines
it's using the built-in renderer to
render the preview node so it has no
knowledge of the actual lighting that's
in Universal RP so this is why when
we're talking about the preview we're
just giving it some preset values that
are you know just safe values we know
it's going to handle these and then we
have essentially what is a snippet out
of universal app he's lighting loops so
in Universal RP there's a lighting HLSL
file it has tons of functions
essentially about getting lights and
getting the information back this is a
very similar kind of sniff it out of
that that goes through get cell light it
gets our main light position color and
etcetera based off where our objects are
really vertices are and then we are
setting the all of our outputs which
defined here up in the actual function
as else and then we're good to go
so this feeds back into our shader graph
shader as variables that we can then
just hook up to anything so now we're
getting the direction of the light we're
getting the color of the light and with
these things we can do you know a dot
product to get our you know lighting
shading on our normal surface and then
there's just some you know
and multiplications and some coloring
from the albedo etc I also do some
masking based on whether it's a leaf or
a trunk and this is a nice way how you
can kind of extend a lot of shader types
in Universal RP without having to you
know write a completely custom shader
from scratch if you just need some
lighting information you want to do a
subsurface you know new translucency
maybe you wanna do a clear coat that's
another thing you can just bring in some
code just to give you the information
that you might not be able to find as a
preset node ready to go one last thing I
want to show in here is the keywords so
if so shader keywords or essentially
they simply duplicate your shader so
they make have multiple versions that
have a certain part of code may be
turned on or turned off so for example
when here I have a keyword to control
the vertex animation so there once the
shader gets compiled there'll be a
version of it without the vertex
animation included and there'll be a
version of it with the vertex animation
included now this makes it so we can
have you know quite efficient shaders if
I don't need the the tree itself to to
be reacting to the wind I can turn that
off and it skips all of that shader code
if I didn't use a keyword and I just did
a branch in the shader say I did a
switch between them it's gonna have to
look at that when it goes to render this
object it's gonna have to check I'm
doing both for these it's more pressure
at the time of rendering whereas here we
can upfront go here's two different
versions of the shader we're only going
to use the one that we wanted the time
these can just be the Edit through the
shadow graph inspector at the blackboard
and there are two types there's a
boolean and there's an enum the boolean
is essentially gives you a tick box of
on and off its keyword that's on or off
an enum will give you a list and then
you can add it multiple entries to the
list so say for example you might want
to do a debug like drop down for your
shader and you have multiple things you
might want to debug out you can then
have this as a switch
as you see here it comes in this is the
vertex animation one this is the boolean
type one it comes in as an on and off
you can feed in what comes in if it's
off you can feed and what happens if
it's on and then you get the like the
output at the end of it so that was a
bit about the shader graph and now I
want to jump over to the camera callback
stuff so to do the planar afflictions
and the spoke demo
it seems she we want to check before any
camera renders whether at the game view
here or the scene view we want to go
okay no we need to render another camera
we need to render a camera that's
flipped and we need to save that out to
a texture that then we can use later on
the water shader so if we have a look at
the planner of fiction script in this
project which is stored in a package
still funnily called lightweight render
pipeline water system but you will see
there the core banks themselves are
quite easy to use so first off here we
subscribe to it so on enable you want to
grab the render pipeline manager and
here we're looking at begin camera
rendering now this will get called every
time a camera and Universal render
pipeline starts its rendering every
single individual camera there's a few
here we can choose from we have begin
camera rendering which was what we're
using begin frame rendering which
happens before we near the cameras have
started you know setting themselves up
and it will actually give you a list of
all the cameras that are going to be
rendered for their frame the big begin
camera rendering will give you the
reference to the camera that's currently
rendering and then we've got in camera
and in frame as well so here I'm just
assigning this explainer of fictions me
that I've got and if we move down one
thing we also got to remember as to what
you think do you locate from it but if
we come down to our planner
actions method down here so execute plan
our fictions and this takes two just
curious because it's been so we've got a
script we're into context which is
provided from the render pipeline itself
this is essentially a lot like a
container of information that the
renderer is holding on to stuff like the
camera or the actual coloring etc and
then we get the camera that is currently
rendering and executing this callback so
in here I just simply go well is it a
reflection camera or was a preview
camera if so I'm not worried about it I
don't want to do planner afflictions for
either of those camera types and then it
does all my code in here which is
sitting up an upside down reflective
camera creating the rendered texture
itself if it hasn't already been created
and you know heading off a render in
Universal render pipeline previously
this was done with camera dot render but
in Universal we're in the pipeline to
make it really nice and easy
weave in to make sure we avoid things
like nested
infinite loops of rear-ending we have
this Universal render pipeline render
single camera and what this lets you do
is as soon as she it renders a single
sharp with the renderer that's currently
applied to the given camera so here I'm
just going I want to render a single
camera I provide my reflection camera
that I've just sit up and it's going to
render into this render texture because
I have assigned it as the target teacher
here and this can be useful for sorts of
things depending on whether you want to
just run some code at the beginning of
the frame beginning of the camera or the
end so now we want to jump over to
essentially the render features so the
scriptable render features all the
scriptable render pass two of them were
created for the steamer if we compile
their script maybe I broke something
severe
I'm gonna go with I probably did break
something so let's just get rid of that
again start again so a few if any of you
here were for the talked earlier about
Universal render pipeline and the
general overview of it all you would
have learned a bit about how the
rendering architecture kind of works and
the idea is that Universal has these
scriptable renderers that you can plug
in plug out the forward renderer that we
supply is currently one of them the 2d
renderer is also one we will be
providing a deferred renderer and you
can make your own in boat demo project
we don't actually create a new renderer
we're just using the default forward
renderer but we have created a few
script or render passes and script or
window features and these are most
notable the caustics which we have here
under the water and then also the water
effects where you can see the trails
behind the boats so first I'll talk a
little bit about the caustics one and if
we go to our renderer we can see our
list of renderer features up here we've
both the caustics renderer feature and a
water effects renderer future now the
caustics one is pretty straightforward
it's got a caustics material which is
just a shader that does i'll explain it
a little bit and a mish that then it
renders so it's similar to the render
objects render feature that is included
in here in the universal render pipeline
but the difference here is that i know
i'm when you're going to render one
object i only need to render that object
exactly a certain way so i wanted a nice
lean render feature that just did this
so I also added a debug so we can look
at exactly what it's doing and it seems
to here you can see a plane a giant
plane that's getting scaled up quite
large it follows the camera it's got
this caustics material assigned to it
and what it does is it takes the depth
texture that's currently been rendered
by the universal render pipeline
inverted to world space coordinates and
then uses those coordinates as UVs for
this caustics texture their thing gets
you know tiled across in a bit of a UV
noise to make the wobbling and this is
quite nice because here if I look at any
of these render pipeline assets
I've got two renderers assigned ones the
boat demo renderer which has the water
affixed in the caustics and once the
plan our reflection renderer the planner
of fiction renderer doesn't need to do
caustic so it doesn't need to do the
water effects because it doesn't see the
water it's rendering underneath the
water and is used purely for the
reflections so why waste rendering time
with this extra feature when we can only
we only need to have it for the vote for
they're essentially the main camera so
this is a again making use of effect
there we can have a default one here
which always use the caustics and the
water fix and then when I create the
planner of fiction camera I tell it to
use the second renderer that's listed in
the pipeline asset if we now look at the
water affects the water effects is it's
hit after rendering the Opaques
and this is essentially a a off-screen
texture so it's rendering to render
texture it's used to control foam and
the offsets so I did
attempts to add a debug but I failed
miserably and it just turns off
post-processing is engineering so it's
good of the frame debugger and actually
show you what's going on there so if we
go into gameplay make sure you get to a
part where we can see some trails from
the bone I'm probably gonna have to turn
off the said machine camera again all my
laptops are really hating me today and
it's locked up again
oh let's come to life okay so let's just
turn off this jumper you can and yeah
that'll do okay so now if we go down to
the frame debugger so we can see
essentially the the makeup of this frame
we enable it I'm just gonna collapse
down these in here you can see it again
it's a bit a bit small so we have all
the essentially script for in the passes
that are getting executed and we have
things like oh wow first off we were
rendering our planet reflection camera
actually currently my render pipeline
assets aren't and in debug mode but if I
was to have it in debug mode you would
see multiple camera Vince essentially so
we'd see the planner of fiction camera
event getting called as its own
standalone group and then the main
camera the reason we have this in a
debug mode on the render pipeline asset
is because getting those pointers and
getting the names of the cameras cause
garbage collection and we don't want
that in your final games so it's only in
the debug mode it's therefore
essentially if you want to see what's
actually rendering and going on while
you're making these systems so here
we're rendering the planner afflictions
and then we go on to rendering our
normal camera so we need our shadows we
get our shadow map and now we go into
our water effects so here we're sitting
up it seems to a clear color of these
were the values that are needed for the
maps that I was creating so this texture
was used to doing normals and for doing
a foam as well as the water displacement
so there's why it ends up being a
society when it fills it in with so this
is essentially what the boats of
rendering in this is some custom shaders
that have a certain shader pasinetta
called water effects and the custom
renderer feature that I created
essentially looks for any shader passes
that have water water effects in the
name and it only renders those shaders
so these are getting rendered all the
time there
essentially trail vendors that are
attached to the boats and particle
renderer that's attached to the boat and
the user getting picked up by this
renderer feature only they're not seen
by the normal rendering so this is
creating well yeah here we can see all
the passes it's creating but this red
channel is used for the phone the green
and blue channels are the normal
channels I can then reuse to create the
offsets and the water shader and then
the Alpha is actually the displacement
so that's why we're at a mid gray so
that we can go up and we can go down and
anything can get rendered into this so
you can create a you know a particle
that's shaped like a wave and we can
have that near the shoreline and okay
wave information that will then get
rendered and used in the water shader to
you know create foam and displacement
and that I think about wraps up
everything in here essentially yeah the
the code itself is quite straightforward
I'll quickly show you some of that just
to explain will savor the water caustics
for example so if we open up the water
caustics feature we have essentially our
scriptable render feature here and this
is again our data container this is
where it holds our water caustic
settings which is our material our mesh
in our debug tick box his little note is
if you do make a essentially a class
that holds your settings and then you
make a public variable called settings
the renderer feature list will
automatically display these settings
there without you having to create a
custom editor and in here there's some
settings for the debug because it's
changing the essentially the blending of
the shader so that we can see it in
debug mode and it goes back to the
crease blending if we're not in debug
mode
we add our in to pass and then here is
our script for in the pass which is our
render water caustics and this is so we
can see in the frame debugger and see it
where it's getting injected in the name
of it here we've got a quick null out if
we don't have a material then we just
exit out we don't want to try and render
anything and from our rendering data
that we come and get gets passed to us
and the execute method of our render
pass we can get the current cameras
position which is going to help us keep
where the the caustics plane is
following the camera we make a matrix
for feeding in to our mesh then we draw
here with the caustics material and then
we can just execute the command buffer
and release it as well afterwards and
this is essentially a custom way of
rendering us a mich itself you can use
to do draw mesh instance you can do it
to draw a full screen quad and do like a
blitz style shader if you have a look at
our universal rendering examples github
repo which we had in previous talk today
there's so much more full out examples
in there of how to set up your own
descriptive or render features so I'd
like to thank you all and we have a bit
of time for questions if anyone has any
[Music]
you